package com.ophiux.common.security.service;

import cn.hutool.core.util.ArrayUtil;
import com.ophiux.common.core.base.Result;
import com.ophiux.common.core.constant.CommonConstants;
import com.ophiux.common.core.constant.SecurityConstants;
import com.ophiux.common.core.enums.UserTypeEnum;
import com.ophiux.common.core.utils.RetOps;
import com.ophiux.system.model.dto.UserInfo;
import com.ophiux.system.model.entity.SysUser;
import org.springframework.core.Ordered;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @desc: 用户接口类扩展
 * @author: hhl
 * @date：2023/12/12 17:14
 */
public interface OphiuxUserDetailsService extends UserDetailsService, Ordered {

    /**
     * 是否支持此客户端校验
     *
     * @param clientId  请求客户端
     * @param grantType 授权类型
     * @return true/false
     */
    default boolean support(String clientId, String grantType) {
        System.out.println("grantType=" + grantType + ",clientId=" + clientId);
        return true;
    }

    /**
     * 排序值 默认取最大的
     *
     * @return 排序值
     */
    default int getOrder() {
        return 0;
    }

    /**
     * 构建userdetails
     *
     * @param result 用户信息
     * @return UserDetails
     * @throws UsernameNotFoundException
     */
    default UserDetails getUserDetails(Result<UserInfo> result) {
        // @formatter:off
        return RetOps.of(result).getData().map(this::convertUserDetails).orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        // @formatter:on
    }

    /**
     * UserInfo 转 UserDetails
     *
     * @param info
     * @return 返回UserDetails对象
     */
    default UserDetails convertUserDetails(UserInfo info) {
        Set<String> dbAuthsSet = new HashSet<>();
        if (ArrayUtil.isNotEmpty(info.getRoles())) {
            // 获取角色
            Arrays.stream(info.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
            // 获取资源
            dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));

        }
        Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
        SysUser user = info.getSysUser();
        // 构造security用户
        return new OphiuxUser(user.getUserId(), user.getUsername(), user.getDeptId(), user.getPhone(), user.getAvatar(), user.getNickname(),
                user.getName(), user.getEmail(), user.getTenantId(), SecurityConstants.BCRYPT + user.getPassword(), true,
                true, UserTypeEnum.TOB.getStatus(), true, !CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
    }

    /**
     * 通过用户实体查询
     *
     * @param ophiuxUser user
     * @return
     */
    default UserDetails loadUserByUser(OphiuxUser ophiuxUser) {
        return this.loadUserByUsername(ophiuxUser.getUsername());
    }

}
